package com.cheer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cheer.common.Page;
import com.cheer.common.PageInfo;
import com.cheer.dao.OaCertDao;
import com.cheer.dao.OaIntegralDao;
import com.cheer.dao.OaUserDao;
import com.cheer.dao.OrganVoDao;
import com.cheer.dto.*;
import com.cheer.entity.*;
import com.cheer.enums.ExchangeTypeEnum;
import com.cheer.exception.ServiceException;
import com.cheer.service.*;
import com.cheer.utils.ExcelsUtil;
import com.cheer.utils.ListPageHelper;
import com.cheer.utils.SmsUtil;
import com.cheer.vo.*;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service("oaUserService")
public class OaUserServiceImpl extends ServiceImpl<OaUserDao, OaUserEntity> implements OaUserService {

    private static  final Logger logger = LoggerFactory.getLogger(OaUserServiceImpl.class);

    @Autowired
    private OaUserDao oaUserDao;

    @Autowired
    private OaLearnClassService oaLearnClassService;

    @Autowired
    private OaLearnEntryService oaLearnEntryService;

    @Autowired
    private OaIntegralService oaIntegralService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private OaChangeHistoryService oaChangeHistoryService;

    @Autowired
    private OaChangeHistoryDetailService oaChangeHistoryDetailService;

    @Autowired
    private OrganVoDao organVoDao;

    @Autowired
    private OaIntegralDao oaIntegralDao;

    @Override
    public Integer getIdByOpenid(String openid) {

        String userIdStr = (String) stringRedisTemplate.boundHashOps("openIdMap").get(openid);
        if( StrUtil.isBlank( userIdStr ) ){
            Integer userId = oaUserDao.selectIdByOpenid(openid);
            if( Objects.isNull(userId) ){
                return null;
            }else{
                stringRedisTemplate.opsForHash().put("openIdMap", openid, String.valueOf(userId));
                return userId;
            }
        }else{
            return Integer.valueOf(userIdStr);
        }
    }

    @Override
    public String getUsernameById(Integer id) {
        return oaUserDao.selectUsernameById(id);
    }

    @Override
    public void refundCredit(Integer id, Integer credit) {
        Integer useIntegral = oaUserDao.selectUserIntegralById(id);
        if (useIntegral != null) {
            int remainCredit = useIntegral - credit;
            if (remainCredit < 0) {
                remainCredit = 0;
            }

            OaUserEntity updateUser = new OaUserEntity();
            updateUser.setId(id)
                    .setUseIntegral(remainCredit);
            oaUserDao.updateById(updateUser);
        }
    }

    @Override
    public void refundFlower(Integer id, int credit) {

        OaUserEntity oaUserEntity = getById(id);
        if (oaUserEntity != null) {
            Integer flower = oaUserEntity.getFlower();
            int remainCredit = flower + credit;
            if (remainCredit < 0) {
                remainCredit = 0;
            }
            OaUserEntity updateUser = new OaUserEntity();
            updateUser.setId(id)
                    .setFlower(remainCredit);
            oaUserDao.updateById(updateUser);
        }
    }

    @Override
    public List<OaUserEntity> getByUserNameAndPhone(String name, String phone) {

        QueryWrapper<OaUserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OaUserEntity::getName, name)
                .eq(OaUserEntity::getPhone, phone).orderByDesc(OaUserEntity::getUpdataTime);
        return list(queryWrapper);
    }

    @Override
    public PageInfo<OaLearnOrgan> getOrganList(OaLearnOrganDto organDto) {

        QueryWrapper<OaLearnOrgan> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<OaLearnOrgan> organVoLambdaQueryWrapper = queryWrapper.lambda()
                .isNotNull(OaLearnOrgan::getOpenId)
                .orderByDesc(OaLearnOrgan::getId);
        if(StringUtils.isNotBlank(organDto.getDept())){
            organVoLambdaQueryWrapper.like(OaLearnOrgan::getDept, organDto.getDept());
        }

        List<OaLearnOrgan> oaLearnOrgans = organVoDao.selectList(organVoLambdaQueryWrapper);
        List<OaLearnOrgan> isNotLearnList = new ArrayList<>(); //未学习的机关人员列表
        List<OaLearnOrgan> isLearnList = new ArrayList<>(); //学习的机关人员列表

        int isLearnNum = 0;
        int isNotLearnNum = 0;

        for (OaLearnOrgan organVo : oaLearnOrgans) {
            String openId = organVo.getOpenId();
            OaUserEntity oaUserEntity = oaUserDao.selectByOpenid(openId);
            organVo.setTotalScore(oaUserEntity == null ? 0 : oaUserEntity.getIntegral());

            //根据openid和items_id和type查询出对应的积分记录
            QueryWrapper<OaIntegralEntity> integralQueryWrapper = new QueryWrapper<>();
            integralQueryWrapper.lambda().eq(OaIntegralEntity::getOpenid, openId)
                    .eq(OaIntegralEntity::getItemsId, organDto.getLearnId());

            //这里无需判断status,只需要查询是否有当前期的积分记录即可
            integralQueryWrapper.lambda().eq(OaIntegralEntity::getType, 2);

            List<OaIntegralEntity> oaIntegralEntities = oaIntegralDao.selectList(integralQueryWrapper);
            if(oaIntegralEntities.size() > 0){
                organVo.setIsLearn(1); //本期已学习
                organVo.setThisScore(oaIntegralEntities.get(0).getIntegral());
                isLearnList.add(organVo);
                isLearnNum ++;
            }else {
                organVo.setIsLearn(0); //未学习
                organVo.setThisScore(organVo.getThisScore() == null ? 0 : organVo.getThisScore());
                isNotLearnList.add(organVo);
                isNotLearnNum++;
            }
        }
        if(organDto.getStatus() == 1){
            //已学习的total
            List<OaLearnOrgan> paging1 = ListPageHelper.paging(isLearnList, organDto.getPageNum(), organDto.getPageSize()); //已分完页的数据集合
            logger.info("已学习的分页total:{}",paging1.size());
            PageInfo<OaLearnOrgan> oaLearnOrganPageInfo = new PageInfo<>(isLearnList, organDto.getPageNum(), organDto.getPageSize());
            oaLearnOrganPageInfo.setList(paging1);
            oaLearnOrganPageInfo.setRows(isLearnList.size());
            return oaLearnOrganPageInfo;
        }else {
            //未学习的total
            List<OaLearnOrgan> paging2 = ListPageHelper.paging(isNotLearnList, organDto.getPageNum(), organDto.getPageSize());
            logger.info("未学习的分页total:{}",paging2.size());
            PageInfo<OaLearnOrgan> oaLearnOrganPageInfo = new PageInfo<>(isNotLearnList, organDto.getPageNum(), organDto.getPageSize());
            oaLearnOrganPageInfo.setList(paging2);
            oaLearnOrganPageInfo.setRows(isNotLearnList.size());
            return oaLearnOrganPageInfo;
        }
    }

    @Override
    public List<String> getOrganDeptList() {
        QueryWrapper<OaLearnOrgan> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<OaLearnOrgan> organVoLambdaQueryWrapper = queryWrapper.lambda()
                .groupBy(OaLearnOrgan::getDept);
        List<OaLearnOrgan> oaLearnOrgans = organVoDao.selectList(organVoLambdaQueryWrapper);
        //lambda获取所有的部门
        List<String> deptList = oaLearnOrgans.stream().map(OaLearnOrgan::getDept).collect(Collectors.toList());
        return deptList;
    }

    @Override
    public void downloadOrgan(OaLearnOrganDto organDto, HttpServletResponse response) {
        QueryWrapper<OaLearnOrgan> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<OaLearnOrgan> organVoLambdaQueryWrapper = queryWrapper.lambda()
                .isNotNull(OaLearnOrgan::getOpenId)
                .orderByDesc(OaLearnOrgan::getId);
        if(StringUtils.isNotBlank(organDto.getDept())){
            organVoLambdaQueryWrapper.like(OaLearnOrgan::getDept, organDto.getDept());
        }

        List<OaLearnOrgan> oaLearnOrgans = organVoDao.selectList(organVoLambdaQueryWrapper);
        List<OaLearnOrgan> isNotLearnList = new ArrayList<>(); //未学习的机关人员列表
        List<OaLearnOrgan> isLearnList = new ArrayList<>(); //学习的机关人员列表

        int isLearnNum = 0;
        int isNotLearnNum = 0;

        for (OaLearnOrgan organVo : oaLearnOrgans) {
            String openId = organVo.getOpenId();
            OaUserEntity oaUserEntity = oaUserDao.selectByOpenid(openId);
            organVo.setTotalScore(oaUserEntity == null ? 0 : oaUserEntity.getIntegral());

            //根据openid和items_id和type查询出对应的积分记录
            QueryWrapper<OaIntegralEntity> integralQueryWrapper = new QueryWrapper<>();
            integralQueryWrapper.lambda().eq(OaIntegralEntity::getOpenid, openId)
                    .eq(OaIntegralEntity::getItemsId, organDto.getLearnId());

            //这里无需判断status,只需要查询是否有当前期的积分记录即可
            integralQueryWrapper.lambda().eq(OaIntegralEntity::getType, 2);

            List<OaIntegralEntity> oaIntegralEntities = oaIntegralDao.selectList(integralQueryWrapper);
            if(oaIntegralEntities.size() > 0){
                organVo.setIsLearn(1); //本期已学习
                organVo.setThisScore(oaIntegralEntities.get(0).getIntegral());
                isLearnList.add(organVo);
                isLearnNum ++;
            }else {
                organVo.setIsLearn(0); //未学习
                organVo.setThisScore(organVo.getThisScore() == null ? 0 : organVo.getThisScore());
                isNotLearnList.add(organVo);
                isNotLearnNum++;
            }
        }
        List<OaLearnOrgan> result = new ArrayList<>();
        if(organDto.getStatus() == 1){
            //已学习的total
            List<OaLearnOrgan> paging1 = ListPageHelper.paging(isLearnList, organDto.getPageNum(), 1000); //已分完页的数据集合
            logger.info("已学习的分页total:{}",paging1.size());
            result = paging1;
        }else {
            //未学习的total
            List<OaLearnOrgan> paging2 = ListPageHelper.paging(isNotLearnList, organDto.getPageNum(), 1000);
            logger.info("未学习的分页total:{}",paging2.size());
            result = paging2;
        }

        List<Map<String, Object>> excelList = new ArrayList<>();
        Map<String, Object> header = new HashMap<>();
        header.put("sheetName", "机关学习表");
        excelList.add(header);

        for (OaLearnOrgan organ : result) {
            Map<String, Object> line = new HashMap<>();
            line.put("name", organ.getName());
            line.put("phone", organ.getPhone());
            line.put("dept", organ.getDept());
            line.put("isLearn", organ.getIsLearn() == 1 ? "已学习" : "未学习");
            line.put("thisScore", organ.getThisScore());
            line.put("totalScore", organ.getTotalScore());
            excelList.add(line);
        }

        String[] columnNames = {"用户名称", "手机号", "所在部门", "本期是否学习", "本期积分", "总积分"};
        String[] keys = {"name", "phone", "dept", "isLearn", "thisScore", "totalScore"};

        response.setContentType("application/x-download");
        response.addHeader("Content-Disposition", "attachment;filename=用户表.xlsx;filename*=UTF-8''"
                + URLUtil.encode("机关学习表.xlsx"));
        try (SXSSFWorkbook xssfWorkbook = ExcelsUtil.ExcelSingleOutputStream(excelList, keys, columnNames)){
            xssfWorkbook.write(response.getOutputStream());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("下载异常");
        }

    }


    @Override
    public Integer getShoppingCredit(Integer userId) {
        OaUserEntity user = oaUserDao.selectIntegralById(userId);
        if (user == null) {
            return null;
        }
        if (user.getUseIntegral() == null) {
            return user.getIntegral();
        } else {
            return user.getIntegral() - user.getUseIntegral();
        }
    }

    @Override
    public void consumeCredit(Integer userId, int credit) {
        Integer useIntegral = oaUserDao.selectUserIntegralById(userId);
        if (useIntegral == null) {
            useIntegral = credit;
        } else {
            useIntegral = useIntegral + credit;
        }
        OaUserEntity updateUser = new OaUserEntity();
        updateUser.setId(userId)
                .setUseIntegral(useIntegral);
        oaUserDao.updateById(updateUser);
    }

    @Override
    public CreditVO getCredit(Integer id) {
        OaUserEntity user = oaUserDao.selectIntegralById(id);
        if (user == null) {
            return null;
        }

        CreditVO creditVO = new CreditVO().setLearnCredit(user.getIntegral());
        creditVO.setShoppingCredit(user.getShopCredit());
        creditVO.setYearCredit(oaIntegralService.getByYear(user.getOpenid(), id));

        return creditVO;
    }



    @Override
    public Page<OaUserListVO> list(OaUserQueryDTO userQueryDTO) {
        if (userQueryDTO.getPid() != 0) {
            OaLearnClassEntity learnClass = oaLearnClassService.getById(userQueryDTO.getPid());
            if (learnClass == null) {
                throw new ServiceException("单位不存在");
            }

            userQueryDTO.setPath(learnClass.getPath() + userQueryDTO.getPid() + ",");
        }

        IPage<OaUserEntity> page = oaUserDao.selectPageByQueryCondition(userQueryDTO);

        Set<String> idSet = new HashSet<>();
        page.getRecords()
                .forEach(user -> {
                    String[] split = StringUtils.split(user.getPath(), ",");
                    idSet.addAll(Lists.newArrayList(split));
                });
        idSet.remove("0");

        Map<Integer, String> map = new HashMap<>();
        if (CollectionUtils.isNotEmpty(idSet)) {
            oaLearnClassService.listByIds(idSet)
                    .forEach(learnClass -> map.put(learnClass.getId(), learnClass.getName()));
        }

        List<OaUserListVO> userListVOList = page.getRecords().stream()
                .map(user -> {
                    OaUserListVO userListVO = new OaUserListVO()
                            .setId(user.getId())
                            .setName(user.getName())
                            .setNickname(user.getNickname())
                            .setSex(user.getSex())
                            .setHeadImgUrl(user.getHeadimgurl())
                            .setType(user.getType())
                            .setPoliticsStatus(user.getPoliticsStatus())
                            .setAddTime(StringUtils.isBlank(user.getAddTime()) ? "" : DateUtil.format(DateUtil.date(
                                    Long.valueOf(user.getAddTime()) * 1000), DatePattern.NORM_DATETIME_PATTERN));

                    String[] split = StringUtils.split(user.getPath(), ",");
                    if (ArrayUtils.isNotEmpty(split)) {
                        List<String> learnClass = new ArrayList<>();
                        for (String str : split) {
                            if (!Objects.equals(str, "0")) {
                                if (map.get(Integer.valueOf(str)) != null) {
                                    learnClass.add(map.get(Integer.valueOf(str)));
                                } else {
                                    break;
                                }
                            }
                        }
                        if (CollectionUtils.isNotEmpty(learnClass)) {
                            userListVO.setLearnClass(StringUtils.join(learnClass, "-"));
                        }
                    }

                    return userListVO;
                })
                .collect(Collectors.toList());

        return new Page<>(page, userListVOList);
    }

    @Override
    public OaUserInfoVO info(Integer id) {
        OaUserEntity user = oaUserDao.selectById(id);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }

        OaUserInfoVO userInfoVO = new OaUserInfoVO()
                .setId(user.getId())
                .setName(user.getName())
                .setNickname(user.getNickname())
                .setSex(user.getSex())
                .setHeadImgUrl(user.getHeadimgurl())
                .setBirthTime(user.getBirthTime())
                .setNativePlace(user.getNativePlace())
                .setType(user.getType())
                .setPoliticsStatus(user.getPoliticsStatus())
                .setProfession(user.getProfession());

        String[] split = StringUtils.split(user.getPath(), ",");
        if (ArrayUtils.isNotEmpty(split)) {
            Set<String> idSet = new HashSet<>(Lists.newArrayList(split));
            idSet.remove("0");

            Map<Integer, String> map = new HashMap<>();
            if (CollectionUtils.isNotEmpty(idSet)) {
                oaLearnClassService.listByIds(idSet)
                        .forEach(learnClass -> map.put(learnClass.getId(), learnClass.getName()));
            }

            List<String> learnClass = new ArrayList<>();
            for (String str : split) {
                if (!Objects.equals(str, "0")) {
                    if (map.get(Integer.valueOf(str)) != null) {
                        learnClass.add(map.get(Integer.valueOf(str)));
                    } else {
                        break;
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(learnClass)) {
                userInfoVO.setLearnClass(StringUtils.join(learnClass, "-"));
            }
        }

        return userInfoVO;
    }

    @Override
    public String getOpenidById(Integer id) {
        return oaUserDao.selectOpenidById(id);
    }

    @Override
    public Page<OaRankListVO> rank(OaRankQueryDTO rankQueryDTO) {
        if (rankQueryDTO.getPid() != 0) {
            OaLearnClassEntity learnClass = oaLearnClassService.getById(rankQueryDTO.getPid());
            if (learnClass == null) {
                throw new ServiceException("单位不存在");
            }

            rankQueryDTO.setPath(learnClass.getPath() + rankQueryDTO.getPid() + ",");
        }

        IPage<OaUserEntity> page = oaUserDao.selectRankPage(rankQueryDTO);

        List<Integer> ids = page.getRecords().stream()
                .map(OaUserEntity::getId)
                .collect(Collectors.toList());
        List<OaUserEntity> userList = CollectionUtils.isEmpty(ids) ? new ArrayList<>()
                : oaUserDao.selectBatchIds(ids);
        Map<Integer, OaUserEntity> userMap = userList.stream()
                .collect(Collectors.toMap(OaUserEntity::getId, Function.identity()));

        Set<String> idSet = new HashSet<>();
        userList.forEach(user -> {
            String[] split = StringUtils.split(user.getPath(), ",");
            idSet.addAll(Lists.newArrayList(split));
        });
        idSet.remove("0");

        Map<Integer, String> map = new HashMap<>();
        if (CollectionUtils.isNotEmpty(idSet)) {
            oaLearnClassService.listByIds(idSet)
                    .forEach(learnClass -> map.put(learnClass.getId(), learnClass.getName()));
        }

        List<OaRankListVO> rankListVOList = page.getRecords().stream()
                .map(oaUserEntity -> {
                    OaUserEntity user = userMap.get(oaUserEntity.getId());
                    if (user == null) {
                        return null;
                    }

                    OaRankListVO rankListVO = new OaRankListVO()
                            .setName(user.getName())
                            .setNickname(user.getNickname())
                            .setSex(user.getSex())
                            .setHeadImgUrl(user.getHeadimgurl())
                            .setType(user.getType())
                            .setPoliticsStatus(user.getPoliticsStatus())
                            .setCredit(user.getIntegral());

                    String[] split = StringUtils.split(user.getPath(), ",");
                    if (ArrayUtils.isNotEmpty(split)) {
                        List<String> learnClass = new ArrayList<>();
                        for (String str : split) {
                            if (!Objects.equals(str, "0")) {
                                if (map.get(Integer.valueOf(str)) != null) {
                                    learnClass.add(map.get(Integer.valueOf(str)));
                                } else {
                                    break;
                                }
                            }
                        }
                        if (CollectionUtils.isNotEmpty(learnClass)) {
                            rankListVO.setLearnClass(StringUtils.join(learnClass, "-"));
                        }
                    }

                    return rankListVO;
                })
                .collect(Collectors.toList());

        return new Page<>(page, rankListVOList);
    }

    @Override
    public List<OaUserEntity> listByOpenids(List<String> openids) {
        if (CollectionUtils.isEmpty(openids)) {
            return new ArrayList<>();
        }

        return oaUserDao.selectListByOpenids(openids);
    }

    @Override
    public OaUserFrontInfoVO frontInfo(Integer id) {
        OaUserEntity user = oaUserDao.selectById(id);
        if (user == null) {
            return null;
        }

        OaUserFrontInfoVO userInfoVO = new OaUserFrontInfoVO()
                .setName(user.getName())
                .setSex(user.getSex())
                .setType(user.getType())
                .setPoliticsStatus(user.getPoliticsStatus())
                .setProfession(user.getProfession())
                .setPhone(user.getPhone());

        String[] split = StringUtils.split(user.getPath(), ",");
        List<Integer> path = new ArrayList<>();
        if (ArrayUtils.isNotEmpty(split)) {
            for (String str : split) {
                if (!StringUtils.equals("0", str)) {
                    path.add(Integer.valueOf(str));
                }
            }
        }

        if (oaLearnClassService.listByIds(path).size() == path.size()) {
            userInfoVO.setPath(path);
        } else {
            userInfoVO.setPath(new ArrayList<>());
        }

        String[] birthTime = user.getBirthTime().split("-");
        if (ArrayUtils.isNotEmpty(birthTime) && birthTime.length == 2) {
            userInfoVO.setBirthYear(birthTime[0])
                    .setBirthMonth(birthTime[1]);
        }

        String[] nativePlace = user.getNativePlace().split("-");
        if (ArrayUtils.isNotEmpty(nativePlace) && nativePlace.length == 2) {
            userInfoVO.setNativePlaceProvince(nativePlace[0])
                    .setNativePlaceCity(nativePlace[1]);
        }

        return userInfoVO;
    }

    @Autowired
    private ExPresentAudioService exPresentAudioService;

    @Override
    public void update(OaUserUpdateDTO userUpdateDTO) {
        OaLearnClassEntity learnClass = oaLearnClassService.getById(Integer.valueOf(userUpdateDTO.getDepartment()));
        if (learnClass == null) {
            throw new ServiceException("所属单位不存在");
        }

        OaUserEntity oldUser = oaUserDao.selectById(userUpdateDTO.getId());
        if (oldUser == null) {
            throw new ServiceException("用户不存在");
        }

        OaUserEntity user = new OaUserEntity();
        BeanUtils.copyProperties(userUpdateDTO, user);
        user.setUpdataTime(String.valueOf(DateUtil.currentSeconds()))
                .setPath(learnClass.getPath() + learnClass.getId() + ",");

        oaUserDao.updateById(user);

        if (!StringUtils.equals(oldUser.getDepartment(), user.getDepartment())) {
            OaLearnEntryEntity oaLearnEntryEntity = new OaLearnEntryEntity()
                    .setOpenid(oldUser.getOpenid())
                    .setDepartment(Integer.valueOf(user.getDepartment()))
                    .setPath(user.getPath());
            oaLearnEntryService.updateByOpenid(oaLearnEntryEntity);

            exPresentAudioService.updateByUserId(user.getId(), user.getDepartment(), user.getPath());
        }
    }

    @Override
    public void download(OaUserQueryDTO userQueryDTO, HttpServletResponse response) {
        if (userQueryDTO.getPid() != 0) {
            OaLearnClassEntity learnClass = oaLearnClassService.getById(userQueryDTO.getPid());
            if (learnClass == null) {
                throw new ServiceException("单位不存在");
            }

            userQueryDTO.setPath(learnClass.getPath() + userQueryDTO.getPid() + ",");
        }

        List<OaUserEntity> list = oaUserDao.selectListByQueryCondition(userQueryDTO);

        Set<String> idSet = new HashSet<>();
        list.forEach(user -> {
            String[] split = StringUtils.split(user.getPath(), ",");
            idSet.addAll(Lists.newArrayList(split));
        });
        idSet.remove("0");

        Map<Integer, String> map = new HashMap<>();
        if (CollectionUtils.isNotEmpty(idSet)) {
            oaLearnClassService.listByIds(idSet)
                    .forEach(learnClass -> map.put(learnClass.getId(), learnClass.getName()));
        }

        List<OaUserListVO> userListVOList = list.stream()
                .map(user -> {
                    OaUserListVO userListVO = new OaUserListVO()
                            .setId(user.getId())
                            .setName(user.getName())
                            .setNickname(user.getNickname())
                            .setSex(user.getSex())
                            .setType(user.getType())
                            .setPoliticsStatus(user.getPoliticsStatus())
                            .setPhone(user.getPhone());

                    String[] split = StringUtils.split(user.getPath(), ",");
                    if (ArrayUtils.isNotEmpty(split)) {
                        List<String> learnClass = new ArrayList<>();
                        for (String str : split) {
                            if (!Objects.equals(str, "0")) {
                                if (map.get(Integer.valueOf(str)) != null) {
                                    learnClass.add(map.get(Integer.valueOf(str)));
                                } else {
                                    break;
                                }
                            }
                        }
                        if (CollectionUtils.isNotEmpty(learnClass)) {
                            userListVO.setLearnClass(StringUtils.join(learnClass, "-"));
                        }
                    }

                    return userListVO;
                })
                .collect(Collectors.toList());

        List<Map<String, Object>> excelList = new ArrayList<>();
        Map<String, Object> header = new HashMap<>();
        header.put("sheetName", "用户表");
        excelList.add(header);

        for (OaUserListVO userListVO : userListVOList) {
            Map<String, Object> line = new HashMap<>();
            line.put("name", userListVO.getName());
            line.put("nickname", userListVO.getNickname());
            line.put("sex", Objects.equals(userListVO.getSex(), 1) ? "男" : "女");
            line.put("politicsStatus", userListVO.getPoliticsStatus());
            line.put("type", userListVO.getType());
            line.put("learnClass", userListVO.getLearnClass());
            line.put("phone", userListVO.getPhone());
            excelList.add(line);
        }

        String[] columnNames = {"用户名称", "微信名称", "性别", "政治面貌", "身份", "机关", "手机号"};
        String[] keys = {"name", "nickname", "sex", "politicsStatus", "type", "learnClass", "phone"};

        response.setContentType("application/x-download");
        response.addHeader("Content-Disposition", "attachment;filename=用户表.xlsx;filename*=UTF-8''"
                + URLUtil.encode("用户表.xlsx"));
        try (SXSSFWorkbook xssfWorkbook = ExcelsUtil.ExcelSingleOutputStream(excelList, keys, columnNames)){
            xssfWorkbook.write(response.getOutputStream());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("下载异常");
        }
    }

    @Override
    public OaRankVO rankInfo(String type, Integer userId) {
        OaRankVO oaRankVO = getOaRankVO(type, userId);
        oaRankVO.setRankList(rankRange(1, 50, String.valueOf(type)));
        return oaRankVO;
    }


    @Override
    public CreditRankVO getRank(Integer userId) {

        // make the query to simple
        OaUserEntity userRankInfo = getById( userId );
        if(userRankInfo == null){
            throw new ServiceException("未查询到当前用户！");
        }
        // rank
        CreditRankVO oaRankVO = new CreditRankVO();

        // 设置缓存全省排名
        oaRankVO.setSelfRankForProvince( getSelfRankForProvince(userRankInfo.getIntegral()));
        // 设置青年排名缓存
        oaRankVO.setSelfRankForYouth( getSelfRankForYouth(userRankInfo.getIntegral(), userRankInfo.getType()));

        // credit
        if (userRankInfo.getUseIntegral() == null) {
            oaRankVO.setShoppingCredit(userRankInfo.getIntegral());
        } else {
            oaRankVO.setShoppingCredit(userRankInfo.getIntegral() - userRankInfo.getUseIntegral());
        }
        oaRankVO.setLearnCredit(userRankInfo.getIntegral());
        oaRankVO.setYearCredit(oaIntegralService.getByYear(userRankInfo.getOpenid(), userId));
        return oaRankVO;
    }

    @Override
    public void consume(Integer userId, int consumeToken, Integer exchangeType) {

        OaUserEntity oaUserEntity = getById(userId);
        if(ExchangeTypeEnum.INTEGRAL.getCode().equals(exchangeType)){
            Integer credit = oaUserEntity.getShopCredit();
            if (credit == null) {
                throw new ServiceException("用户不存在");
            }
            if (credit < consumeToken) {
                throw new ServiceException("积分不足");
            }
            // 扣除积分
            consumeCredit(userId, consumeToken);
        }
        if(ExchangeTypeEnum.FLOWER.getCode().equals(exchangeType)){
            if(oaUserEntity.getFlower() < consumeToken){
                throw new ServiceException("小红花数量不足");
            }else{
                oaUserEntity.consumeFlower(consumeToken);
            }
            // 扣除小红花
            oaUserDao.updateById(oaUserEntity);
        }
    }

    @Override
    public void addFlower(Integer userId, Integer consumeIntegral, Integer exchangeNum) {

        consumeCredit(userId, consumeIntegral);
        OaUserEntity oaUserEntity = oaUserDao.selectById(userId);
        oaUserEntity.addFlower(exchangeNum);

        UpdateWrapper<OaUserEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .set(OaUserEntity::getFlower, oaUserEntity.getFlower())
                .eq(OaUserEntity::getId, userId);
        update(updateWrapper);
    }



    private Integer getSelfRankForYouth(Integer integral, String type) {

        String busiKey = "mall_rank_province_" + integral;
        String rank = stringRedisTemplate.boundValueOps(busiKey).get();
        if( StrUtil.isBlank( rank ) ){
            rank =  String.valueOf(oaUserDao.selectCountByTypeGe(integral, type) + 1);
            // 设置五分钟后过期
            stringRedisTemplate.opsForValue().set( busiKey, rank, 2, TimeUnit.DAYS);
        }
        return Integer.valueOf(rank);
    }

    private Integer getSelfRankForProvince(Integer integral) {
        // 抵御高峰的时候执行过多的数据库操作
        String busiKey = "mall_rank_" + integral;
        String rank = stringRedisTemplate.boundValueOps(busiKey).get();
        if( StrUtil.isBlank( rank ) ){
            rank =  String.valueOf(oaUserDao.selectCountByIntegralGe(integral) + 1);
            // 设置五分钟后过期
            stringRedisTemplate.opsForValue().set( busiKey, rank, 2, TimeUnit.DAYS);
        }
        return Integer.valueOf(rank);
    }

    private OaRankVO getOaRankVO(String type, Integer userId) {
        OaRankVO oaRankVO = new OaRankVO();
        OaUserEntity user = oaUserDao.selectById(userId);
        if (user != null) {
            oaRankVO.setType(user.getType());
            if (Objects.equals(type, "全部")) {
                oaRankVO.setSelfRank(getSelfRankForProvince(user.getIntegral()));
            } else {
                oaRankVO.setSelfRank(oaUserDao.selectCountByTypeGe(user.getIntegral(), user.getType()) + 1);
            }
        }
        return oaRankVO;
    }


    @Override
    public List<OaRankItemVO> rankRange(Integer pageNum, Integer pageSize, String type) {
        int start = (pageNum - 1) * pageSize;
        int offset = pageSize;

        List<OaUserEntity> creditRecordList;
        if (StringUtils.equals(type, "全部")) {
            creditRecordList = oaUserDao.selectListByIntegralLimit(start, offset);
        } else {
            creditRecordList = oaUserDao.selectListByTypeLimit(start, offset, type);
        }

        Set<String> idSet = new HashSet<>();
        creditRecordList.forEach(user -> {
            String[] split = StringUtils.split(user.getPath(), ",");
            idSet.addAll(Lists.newArrayList(split));
        });
        idSet.remove("0");

        Map<Integer, String> map = new HashMap<>();
        if (CollectionUtils.isNotEmpty(idSet)) {
            oaLearnClassService.listByIds(idSet)
                    .forEach(learnClass -> map.put(learnClass.getId(), learnClass.getName()));
        }

        return creditRecordList.stream()
                .map(oaUserEntity -> {
                    OaRankItemVO oaRankItemVO = new OaRankItemVO()
                            .setName(oaUserEntity.getName())
                            .setCredit(oaUserEntity.getIntegral())
                            .setHeadImgUrl(oaUserEntity.getHeadimgurl());

                    String[] split = StringUtils.split(oaUserEntity.getPath(), ",");
                    if (ArrayUtils.isNotEmpty(split)) {
                        List<String> learnClass = new ArrayList<>();
                        for (String str : split) {
                            if (!Objects.equals(str, "0")) {
                                if (map.get(Integer.valueOf(str)) != null) {
                                    learnClass.add(map.get(Integer.valueOf(str)));
                                } else {
                                    break;
                                }
                            }
                        }
                        if (CollectionUtils.isNotEmpty(learnClass)) {
                            oaRankItemVO.setLearnClass(StringUtils.join(learnClass, "-"));
                        }
                    }

                    return oaRankItemVO;
                })
                .collect(Collectors.toList());
    }

    @Override
    public void downloadRank(OaRankQueryDTO rankQueryDTO, HttpServletResponse response) {
        // 下级单位没有下载排名
        if (rankQueryDTO.getPid() != 0) {
            OaLearnClassEntity learnClass = oaLearnClassService.getById(rankQueryDTO.getPid());
            if (learnClass == null) {
                throw new ServiceException("单位不存在");
            }

            rankQueryDTO.setPath(learnClass.getPath() + rankQueryDTO.getPid() + ",");
        }

        List<OaUserEntity> list = oaUserDao.selectRankList(rankQueryDTO);

        Set<String> idSet = new HashSet<>();
        list.forEach(user -> {
            String[] split = StringUtils.split(user.getPath(), ",");
            idSet.addAll(Lists.newArrayList(split));
        });
        idSet.remove("0");

        Map<Integer, String> map = new HashMap<>();
        if (CollectionUtils.isNotEmpty(idSet)) {
            oaLearnClassService.listByIds(idSet)
                    .forEach(learnClass -> map.put(learnClass.getId(), learnClass.getName()));
        }

        List<OaRankListVO> rankListVOList = list.stream()
                .map(user -> {
                    OaRankListVO rankListVO = new OaRankListVO()
                            .setName(user.getName())
                            .setNickname(user.getNickname())
                            .setSex(user.getSex())
                            .setHeadImgUrl(user.getHeadimgurl())
                            .setType(user.getType())
                            .setPoliticsStatus(user.getPoliticsStatus())
                            .setCredit(user.getIntegral());

                    String[] split = StringUtils.split(user.getPath(), ",");
                    if (ArrayUtils.isNotEmpty(split)) {
                        List<String> learnClass = new ArrayList<>();
                        for (String str : split) {
                            if (!Objects.equals(str, "0")) {
                                if (map.get(Integer.valueOf(str)) != null) {
                                    learnClass.add(map.get(Integer.valueOf(str)));
                                } else {
                                    break;
                                }
                            }
                        }
                        if (CollectionUtils.isNotEmpty(learnClass)) {
                            rankListVO.setLearnClass(StringUtils.join(learnClass, "-"));
                        }
                    }

                    return rankListVO;
                })
                .collect(Collectors.toList());

        List<Map<String, Object>> excelList = new ArrayList<>();
        Map<String, Object> header = new HashMap<>();
        header.put("sheetName", "学习排名表");
        excelList.add(header);

        int i = 1;
        for (OaRankListVO rankListVO : rankListVOList) {
            Map<String, Object> line = new HashMap<>();
            line.put("rank", i++);
            line.put("name", rankListVO.getName());
            line.put("nickname", rankListVO.getNickname());
            line.put("sex", Objects.equals(rankListVO.getSex(), 1) ? "男" : "女");
            line.put("politicsStatus", rankListVO.getPoliticsStatus());
            line.put("type", rankListVO.getType());
            line.put("learnClass", rankListVO.getLearnClass());
            line.put("credit", rankListVO.getCredit());
            excelList.add(line);
        }

        String[] columnNames = {"排名", "用户名称", "微信名称", "性别", "政治面貌", "身份", "机关", "积分"};
        String[] keys = {"rank", "name", "nickname", "sex", "politicsStatus", "type", "learnClass", "credit"};

        response.setContentType("application/x-download");
        response.addHeader("Content-Disposition", "attachment;filename=学习排名表.xlsx;filename*=UTF-8''"
                + URLUtil.encode("学习排名表.xlsx"));
        try (SXSSFWorkbook xssfWorkbook = ExcelsUtil.ExcelSingleOutputStream(excelList, keys, columnNames)){
            xssfWorkbook.write(response.getOutputStream());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("下载异常");
        }
    }

    @Override
    public OaUserEntity getByOpenid(String openid) {
        return oaUserDao.selectByOpenid(openid);
    }

    @Override
    public void addCredit(Integer id, Integer credit) {
        oaUserDao.updateIntegral(id, credit);
        oaIntegralService.updateYearCatch( id, credit);
    }

    @Override
    public String getUpdateTimeById(Integer id) {
        return oaUserDao.selectUpdateTimeById(id);
    }

    @Override
    public void updateHead(Integer id, String headimgurl) {
        OaUserEntity user = new OaUserEntity()
                .setId(id)
                .setHeadimgurl(headimgurl);
        oaUserDao.updateById(user);
    }

    @Override
    public void updatePathByDepartment(Integer department, String path) {
        oaUserDao.updatePathByDepartment(department, path);
    }

    @Autowired
    private OaCertDao oaCertDao;

    @Override
    public OaCertVO cert(Integer userId) {
        OaCertEntity oaCertEntity = oaCertDao.selectByUserId(userId);
        if (oaCertEntity == null) {
            return new OaCertVO().setIsCert(false);
        }
        return new OaCertVO().setIsCert(true).setCertNumber(oaCertEntity.getCertNumber())
                .setRealName(oaCertEntity.getRealName());
    }

    @Override
    public void updateCert(OaCertDTO oaCertDTO) {
        OaCertEntity oaCertEntity = oaCertDao.selectByUserId(oaCertDTO.getUserId());
        if (oaCertEntity == null) {
            OaCertEntity insert = new OaCertEntity()
                    .setUserId(oaCertDTO.getUserId())
                    .setCertNumber(oaCertDTO.getCertNumber())
                    .setRealName(oaCertDTO.getRealName());
            oaCertDao.insert(insert);
            return;
        }
        oaCertEntity.setRealName(oaCertDTO.getRealName())
                .setCertNumber(oaCertDTO.getCertNumber());
        oaCertDao.updateById(oaCertEntity);
    }

    @Override
    public String change(OaUserChangeDTO userChangeDTO, HttpSession session) {

        // 查询系统中符合条件的用户
        QueryWrapper<OaUserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(OaUserEntity::getName, userChangeDTO.getName())
                .eq(OaUserEntity::getPhone, userChangeDTO.getPhone())
                .eq(OaUserEntity::getBirthTime, userChangeDTO.getBirthTime())
                .eq(OaUserEntity::getDepartment, userChangeDTO.getDepartment());

        List<OaUserEntity> oaUserEntities = oaUserDao.selectList(queryWrapper);

        if(CollectionUtil.isEmpty(oaUserEntities)){
            throw new ServiceException("未查询到当前用户！");
        }
        if(oaUserEntities.size() > 1){
            throw new ServiceException("存在多个相同用户！");
        }
        OaUserEntity oaUserEntity = oaUserEntities.get(0);
        Integer currentUserId = (Integer)session.getAttribute("userId");
        OaUserEntity currentUser = oaUserDao.selectIntegralById(currentUserId);

        String sendTimeStr = stringRedisTemplate.opsForValue().get(currentUser.getOpenid());
        Integer sendTime = 0;
        if(sendTimeStr != null){
            sendTime = Integer.valueOf(sendTimeStr);
        }
        if(sendTime > 5){
            throw new ServiceException("验证码已经超过今天的最大发送次数！");
        }
        if(currentUserId.equals(oaUserEntity.getId())){
            throw new ServiceException("被合并的账号不能与当前登陆账号相同！");
        }
        String checkCode = stringRedisTemplate.opsForValue().get(session.getId());
        if(StrUtil.isBlank(checkCode)){
            // 调用短信接口
            checkCode = RandomUtil.randomNumbers(4);
            // 验证码存入到redis中
            Map<String, String> map = new HashMap<>();
            map.put("checkCode",checkCode);
            map.put("userId", String.valueOf(oaUserEntity.getId()));
            try {
                System.out.println("当前手机号" + oaUserEntity.getPhone());
                System.out.println("当前验证码" + checkCode);
                SmsUtil.send(oaUserEntity.getPhone(), checkCode);
                stringRedisTemplate.opsForValue().set(session.getId(), JSON.toJSONString(map),  2, TimeUnit.MINUTES);
                stringRedisTemplate.opsForValue().set(currentUser.getOpenid(), String.valueOf(sendTime + 1),1, TimeUnit.DAYS);
                return checkCode;
            }catch (Exception e){
                log.error(e.getMessage());
                throw new ServiceException("发送验证码失败！");
            }
        }else{
            throw new ServiceException("请勿重复发送验证码！");
        }
    }

    @Override
    public Integer transfer(String checkCode, HttpSession session) {

        if(StrUtil.isBlank(checkCode) || checkCode.length() != 4){
            throw new ServiceException("验证码错误！");
        }
        String message = stringRedisTemplate.opsForValue().get(session.getId());

        if(StrUtil.isEmpty(message)){
            throw new ServiceException("验证码错误！");
        }
        // 验证验证码
        Map<String, String> messageMap = JSON.parseObject(message, HashMap.class);
        String sendCode = messageMap.get("checkCode");
        Integer sourceUserId = Integer.valueOf(messageMap.get("userId"));
        if(checkCode.equals(sendCode)){
            Integer targetUserId = (Integer)session.getAttribute("userId");
            Integer differ = transfer(sourceUserId, targetUserId);
            return differ;
        }else{
            throw new ServiceException("验证码错误！");
        }
    }



    @Transactional
    public Integer transfer(Integer sourceUserId, Integer targetUserId) {

        Integer differ = 0;

        // 2. 更新积分记录
        OaUserEntity sourceUser = oaUserDao.selectById(sourceUserId);
        OaUserEntity targetUser = oaUserDao.selectById(targetUserId);
        // 查询学习记录
        List<OaIntegralEntity> sourceEntities = oaIntegralService.listByUserId2(sourceUserId);
        List<OaIntegralEntity> targetEntities = oaIntegralService.listByUserId2(targetUserId);
        Map<String, List<OaIntegralEntity>>  mergeRecord = merge(sourceEntities, targetEntities, targetUser.getOpenid());

        List<OaIntegralEntity> replenish = mergeRecord.get("replenish");
        List<OaIntegralEntity> targetRemove = mergeRecord.get("targetRemove");
        List<OaIntegralEntity> sourceRemove = mergeRecord.get("sourceRemove");

        // 保存补充之后的积分记录
        if(CollectionUtil.isNotEmpty(replenish)){
            oaIntegralService.saveBatch(replenish);
        }
        // 删除目标积分记录
        List<Long> sourceIdList = new ArrayList<>();
        for (OaIntegralEntity sourceEntity : sourceEntities) {
            sourceIdList.add(sourceEntity.getId());
        }
        // 删除冲突积分
        if (CollectionUtil.isNotEmpty(sourceIdList)) {
            oaIntegralService.removeByIds(sourceIdList);
        }
        if(CollectionUtil.isNotEmpty(targetRemove)){
            List<Long> removeIds = targetRemove.stream().map(OaIntegralEntity::getId).collect(Collectors.toList());
            oaIntegralService.removeByIds(removeIds);
        }

        Optional<Integer> reduceIntergralOptional = sourceRemove.stream().map(OaIntegralEntity::getIntegral).reduce(Integer::sum);
        differ = sourceUser.getIntegral() - reduceIntergralOptional.orElse(0);

        // 1. 更新新用户积分
        if(differ > 0 ){
            targetUser.setIntegral(targetUser.getIntegral() + differ );
            oaUserDao.updateById(targetUser);
        }else{
            differ = 0;
        }
        // 1. 还原老用户积分
        sourceUser.setIntegral(0);
        sourceUser.setUseIntegral(0);
        oaUserDao.updateById(sourceUser);
        // 记录积分转换操作
        OaChangeHistoryEntity oaChangeHistoryEntity = new OaChangeHistoryEntity();
        oaChangeHistoryEntity.setSourceId(sourceUser.getId());
        oaChangeHistoryEntity.setTargetId(targetUser.getId());
        oaChangeHistoryEntity.setAddTime(new Date());
        oaChangeHistoryService.save(oaChangeHistoryEntity);

        // 记录被操作的积分信息
        Integer historyId = oaChangeHistoryEntity.getId();
        List<OaChangeHistoryDetailEntity> result = new ArrayList<>();
        // 删除为0 新增为1
        result.addAll(convert(targetRemove, historyId,  0));
        result.addAll(convert(replenish, historyId,  1));

        if(CollectionUtil.isNotEmpty(result)){
            oaChangeHistoryDetailService.saveBatch(result);
        }
        return differ;
    }

    private List<OaChangeHistoryDetailEntity> convert( List<OaIntegralEntity> targetRemove, Integer historyId, Integer opt ) {

        if( CollectionUtils.isNotEmpty(targetRemove)){
            List<OaChangeHistoryDetailEntity> removeRecords = targetRemove.stream().map(removeRecord -> {
                Long id = removeRecord.getId();
                OaChangeHistoryDetailEntity tempObj = BeanUtil.copyProperties(removeRecord, OaChangeHistoryDetailEntity.class, "id");
                tempObj.setHistoryId(historyId);
                tempObj.setIntegralId(id);
                tempObj.setOptType(opt);
                return tempObj;
            }).collect(Collectors.toList());
            return removeRecords;
        }
        return new ArrayList<>();
    }

    private Map< String, List<OaIntegralEntity>>  merge(List<OaIntegralEntity> sourceEntities, List<OaIntegralEntity> targetEntities, String targetOpenId) {

        Map<String, List<OaIntegralEntity>> map = new HashMap<>();
        List<OaIntegralEntity> result = new ArrayList<>();

        Map<String, OaIntegralEntity> sourceMap = convertToMap(sourceEntities);
        Map<String, OaIntegralEntity> targetMap = convertToMap(targetEntities);
        Set<String> sourceMapKeys = sourceMap.keySet().stream().collect(Collectors.toSet());
        Set<String> targetMapKeys = targetMap.keySet().stream().collect(Collectors.toSet());
        sourceMapKeys.retainAll(targetMapKeys);
        List<OaIntegralEntity> targetRemoveRecord = new ArrayList<>();
        List<OaIntegralEntity> sourceRemoveRecord = new ArrayList<>();
        Iterator<String> iterator = sourceMapKeys.iterator();
        while(iterator.hasNext()){
            String repeatKey = iterator.next();
            OaIntegralEntity source = sourceMap.get(repeatKey);
            OaIntegralEntity target = targetMap.get(repeatKey);
            // 删除较小的值
            if(source.getIntegral().compareTo(target.getIntegral()) == -1){
                sourceMap.remove(repeatKey);
                sourceRemoveRecord.add(source);
            }else if(source.getIntegral().compareTo(target.getIntegral()) == 0){
                sourceMap.remove(repeatKey);
                sourceRemoveRecord.add(source);
            }else{
                targetMap.remove(repeatKey);
                targetRemoveRecord.add(target);
            }
        }

        List<OaIntegralEntity> sourceList =  sourceMap.values().stream().collect(Collectors.toList());
        List<OaIntegralEntity> targetList =  targetMap.values().stream().collect(Collectors.toList());
        result.addAll(sourceList);
        result.addAll(targetList);
        sourceList.forEach( oaIntegralEntity -> {
            oaIntegralEntity.setId(null);
            oaIntegralEntity.setOpenid(targetOpenId);
        });

        // 总记录
        map.put("count", result);
        // 需要补充的记录
        map.put("replenish", sourceList);
        // 需要删除目标的记录
        map.put("targetRemove", targetRemoveRecord);
        // 需要删除源表记录
        map.put("sourceRemove", sourceRemoveRecord);
        return map;
    }

    private Map<String, OaIntegralEntity> convertToMap(List<OaIntegralEntity> sourceEntities) {

        Map<String, OaIntegralEntity> map = new HashMap<>();
        for (int i = 0; i < sourceEntities.size(); i++) {
            OaIntegralEntity oaIntegralEntity = sourceEntities.get(i);
            String key = oaIntegralEntity.getType() + "_" + oaIntegralEntity.getItemsId() + "_" + DateUtil.format(oaIntegralEntity.getAddTime(), "yyyy-MM-dd");
            map.put(key, oaIntegralEntity);
        }
        return map;
    }


}